<?php

/**
 * 狡兔之基础类 模拟：web service
 * 来源：狡兔三窟，说明兔子行动最谨慎。
 * User: sgfoot
 * Date: 2017/3/20
 * Time: 10:33
 */
class CoonBase
{
    /**定义新数组*/
    protected $values = array();
    protected $key = '';
    protected $timeout = 30;//超时设置

    /**
     * 初使化
     */
    public function __construct()
    {
        date_default_timezone_set('PRC');//初使北京时间
    }

    /**
     * 设置开关
     * @param bool $isOpen 开关
     * @author: wzl
     * @date: 2017
     */
    public function setOpen($isOpen = true)
    {
        $this->values['open'] = $isOpen;
    }

    /**
     * 设置密钥
     * @param $appId string 密钥ID
     * @param $appKey string 密钥key
     * @author: wzl
     * @date: 2017
     */
    public function setKey($appKey)
    {
        $this->key = $appKey;
    }

    /**
     * 获取curl 请求过来的数据。
     * @return string
     */
    public function getRequest()
    {
        return file_get_contents("php://input");
    }

    /**
     * 获取整个数组
     * @return array 返回数组
     */
    public function getValues()
    {
        return $this->values;
    }

    /**
     * 返回请求的data数据
     * @return mix 返回请求的数据
     */
    public function getData()
    {
        return $this->values['data'];
    }

    /**
     * 获取数组中的SIGN
     * @return string 返回大写的SIGN
     */
    public function getSign()
    {
        return $this->values['sign'];
    }

    /**
     * 设置需要传输的数据
     * @param array $data 数组，不限维度
     */
    public function setData($data)
    {
        $this->values['data'] = $data;
    }

    /**
     * 设置SIGN
     * @return string 返回大写的SIGN
     */
    public function setSign()
    {
        $sign = $this->makeSign();
        $this->values['sign'] = $sign;
        return $sign;
    }

    /**
     * 将JSON转换成ARRAY
     * @param string $json 数据
     * @return array 数组
     */
    public function toArray($json)
    {
        $this->values = json_decode($json, true);
        return $this->values;
    }

    /**
     * 将ARRAY转换换JSON
     * @return string json数据
     */
    public function toJson()
    {
        ksort($this->values);
        return json_encode($this->values);
    }

    /**
     * 将数组拼接成字符串
     * @param array $params 数组数据
     * @return string
     */
    protected function toString(array $params)
    {
        if (is_array($params)) {
            $string = '';
            foreach ($params as $key => $value) {
                if ($key != 'sign') {//排除sign，不参与加密
                    $string .= $key . '=' . $value . '&';
                }
            }
            $new_string = rtrim($string, '&');
            return $new_string;
        }
        return '';
    }

    /**
     * 生成SIGN
     * @return string 返回大写SIGN
     */
    public function makeSign()
    {
        $param_arr = $this->toOneArray();
        ksort($param_arr);//词典排序
        $param_string = $this->toString($param_arr);//将数组转换成字符串
        $sign = md5(md5($param_string) . $this->key);//加密形成SIGN
        return strtoupper($sign);//转换成大写
    }

    /**
     * 设置唯一变化值。以防攻击
     */
    public function setOnly()
    {
        $this->setTime();
        $this->setNonce();
    }

    /**
     * 设置时间
     */
    protected function setTime()
    {
        $this->values['time'] = time();
    }

    /**
     * 设置随机码
     */
    protected function setNonce()
    {
        $this->values['nonce'] = $this->getNonceStr();
    }

    /**
     * 设置返回值，
     * @param int $status 返回状态值 0为成功，其它值异常
     * @param mix $data 【可选】返回的数据
     * @return string 返回的json值 （已将array转换成json）
     */
    public function setReturn($status, $data = array())
    {
        $return = array(
            'status' => $status,
            'msg' => $data,
        );
        return json_encode($return);
    }

    /**
     *
     * 产生随机字符串，不长于32位
     * @param int $length
     * @return 产生的随机字符串
     */
    protected static function getNonceStr($length = 32)
    {
        $chars = "abcdefghijklmnopqrstuvwxyz0123456789";
        $str = "";
        for ($i = 0; $i < $length; $i++) {
            $str .= substr($chars, mt_rand(0, strlen($chars) - 1), 1);
        }
        return $str;
    }

    /**
     * 将多维数组转换成一维数组
     */
    protected function toOneArray()
    {
        $param_arr = array();//新定义一个数组
        foreach ($this->values as $key => $val) {
            if (is_array($val)) {//数组的则进行序列化
                $param_arr[$key] = serialize($val);
            } else {//非数组的不序列化
                $param_arr[$key] = $val;
            }
        }
        return $param_arr;
    }

    /**
     * curl 传输数据
     * @param string $url 有效url
     * @param string $json json数据
     * @return string 结果
     */
    public function postJsonCurl($url, $json)
    {
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $json);
        curl_setopt($ch, CURLOPT_TIMEOUT, $this->timeout);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json;charset=utf-8',
            'Content-Length:' . strlen($json)));
        $result = curl_exec($ch);
        curl_close($ch);
        return $result;
    }
}